package aparapi;

import com.aparapi.Kernel;
import com.aparapi.device.OpenCLDevice;
import com.aparapi.internal.opencl.OpenCLPlatform;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

/**
 * @Description 使用Aparapi的一些案例
 * @Date 2022/3/25 18:15
 * @Author eric ling
 */
public class AparapiTest {

    @Test
    public void findInArray() {
        final int[] buffer = new int[1024];
        Arrays.fill(buffer, -1);
        buffer[102] = 1234;
        final boolean[] found = {false};
        Kernel kernel = new Kernel() {
            @Override
            public void run() {
                if (buffer[getGlobalId()] == 1234) {
                    found[0] = true;
                }
            }
        };
        kernel.execute(buffer.length);
        System.out.println(found[0]);
    }


    @Test
    public void deviceQuery() {
        System.out.println("设备信息：");
        List<OpenCLPlatform> platforms = new OpenCLPlatform().getOpenCLPlatforms();
        System.out.println("Machine contains " + platforms.size() + " OpenCL platforms");
        int platformc = 0;
        for (OpenCLPlatform platform : platforms) {
            System.out.println("Platform " + platformc + "{");
            System.out.println("   Name    : \"" + platform.getName() + "\"");
            System.out.println("   Vendor  : \"" + platform.getVendor() + "\"");
            System.out.println("   Version : \"" + platform.getVersion() + "\"");
            List<OpenCLDevice> devices = platform.getOpenCLDevices();
            System.out.println("   Platform contains " + devices.size() + " OpenCL devices");
            int devicec = 0;
            for (OpenCLDevice device : devices) {
                System.out.println("   Device " + devicec + "{");
                System.out.println("       Type                  : " + device.getType());
                System.out.println("       GlobalMemSize         : " + device.getGlobalMemSize());
                System.out.println("       LocalMemSize          : " + device.getLocalMemSize());
                System.out.println("       MaxComputeUnits       : " + device.getMaxComputeUnits());
                System.out.println("       MaxWorkGroupSizes     : " + device.getMaxWorkGroupSize());
                System.out.println("       MaxWorkItemDimensions : " + device.getMaxWorkItemDimensions());
                System.out.println("   }");
                devicec++;
            }
            System.out.println("}");
            platformc++;
        }

    }

    @Test
    public void explicitBufferManagement() {
        final int[] hugeArray = new int[4096];
        final int[] done = new int[]{0};
        Kernel kernel = new Kernel() {
            @Override
            public void run() {
                // reads/writes hugeArray and writes to done[0] when complete
            }
        };
        kernel.setExplicit(true); // 手动管理数据的拷贝(H2D,D2H)
        done[0] = 0;
        kernel.put(done); // 送入device仅一次
        kernel.put(hugeArray); // 送入device仅一次
        while (done[0] == 0) {
            kernel.execute(hugeArray.length);
            kernel.get(done); //每次迭代 都从device中拷贝数据
        }
        kernel.get(hugeArray);
        kernel.cleanUpArrays();
        kernel.dispose();
    }
}
